home *** CD-ROM | disk | FTP | other *** search
- /* toolbar implementation -- X interface.
- Copyright (C) 1995 Board of Trustees, University of Illinois.
- Copyright (C) 1995 Sun Microsystems.
-
- This file is part of XEmacs.
-
- XEmacs is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- XEmacs is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License
- along with XEmacs; see the file COPYING. If not, write to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Synched up with: Not in FSF. */
-
- #include <config.h>
- #include "lisp.h"
-
- #include "device-x.h"
- #include "faces.h"
- #include "frame-x.h"
- #include "glyphs-x.h"
- #include "objects-x.h"
- #include "toolbar.h"
- #include "window.h"
- #include "xgccache.h"
- #include "EmacsFrame.h"
- #include "EmacsFrameP.h"
- #include "EmacsManager.h"
-
- static void
- x_draw_blank_toolbar_button (struct frame *f, int x, int y, int width,
- int height, int threed)
- {
- struct device *d = XDEVICE (f->device);
- EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
- int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
-
- Display *dpy = DEVICE_X_DISPLAY (d);
- Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
- GC top_shadow_gc, bottom_shadow_gc, background_gc;
-
- background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
-
- if (threed)
- {
- top_shadow_gc = FRAME_X_TOOLBAR_TOP_SHADOW_GC (f);
- bottom_shadow_gc = FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f);
- }
- else
- {
- top_shadow_gc = background_gc;
- bottom_shadow_gc = background_gc;
- }
-
- /* Draw the outline. */
- x_output_shadows (f, x, y, width, height, top_shadow_gc,
- bottom_shadow_gc, background_gc, shadow_thickness);
-
- /* Blank the middle. */
- XFillRectangle (dpy, x_win, background_gc, x + shadow_thickness,
- y + shadow_thickness, width - shadow_thickness * 2,
- height - shadow_thickness * 2);
- }
-
- static void
- x_output_toolbar_button (struct frame *f, Lisp_Object button)
- {
- struct device *d = XDEVICE (f->device);
- EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
- int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
-
- Display *dpy = DEVICE_X_DISPLAY (d);
- Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
- GC top_shadow_gc, bottom_shadow_gc, background_gc;
- Lisp_Object instance, frame, window, glyph;
- struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
- struct Lisp_Image_Instance *p;
- struct window *w;
-
- XSETFRAME (frame, f);
- window = FRAME_SELECTED_WINDOW (f);
- w = XWINDOW (window);
-
- /* See comment in x_get_button_size for the logic to determine which
- glyph is to be used. */
-
- glyph = Qnil;
- if (!NILP (w->toolbar_buttons_captioned_p))
- {
- if (tb->enabled && tb->down)
- glyph = tb->cap_down_glyph;
- else if (!tb->enabled)
- glyph = tb->cap_disabled_glyph;
-
- if (NILP (glyph))
- glyph = tb->cap_up_glyph;
- }
-
- if (NILP (glyph))
- {
- if (tb->enabled && tb->down)
- glyph = tb->down_glyph;
- else if (!tb->enabled)
- glyph = tb->disabled_glyph;
- }
-
- if (NILP (glyph))
- glyph = tb->up_glyph;
-
- assert (!NILP (glyph));
-
- if (tb->enabled)
- {
- if (tb->down)
- {
- top_shadow_gc = FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f);
- bottom_shadow_gc = FRAME_X_TOOLBAR_TOP_SHADOW_GC (f);
- }
- else
- {
- top_shadow_gc = FRAME_X_TOOLBAR_TOP_SHADOW_GC (f);
- bottom_shadow_gc = FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f);
- }
- }
- else
- {
- top_shadow_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
- bottom_shadow_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
- }
- background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
-
- instance = glyph_image_instance (glyph, window, 1);
-
- /* Draw the outline. */
- x_output_shadows (f, tb->x, tb->y, tb->width, tb->height, top_shadow_gc,
- bottom_shadow_gc, background_gc, shadow_thickness);
-
- /* Clear the pixmap area. */
- XFillRectangle (dpy, x_win, background_gc, tb->x + shadow_thickness,
- tb->y + shadow_thickness, tb->width - shadow_thickness * 2,
- tb->height - shadow_thickness * 2);
-
- background_gc = FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f);
-
- if (IMAGE_INSTANCEP (instance))
- {
- int width = tb->width - shadow_thickness * 2;
- int height = tb->height - shadow_thickness * 2;
- int x_offset = shadow_thickness;
- int y_offset = shadow_thickness;
-
- p = XIMAGE_INSTANCE (instance);
-
- if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p))
- {
- if (width > (int) IMAGE_INSTANCE_PIXMAP_WIDTH (p))
- {
- x_offset += ((int) (width - IMAGE_INSTANCE_PIXMAP_WIDTH (p))
- / 2);
- width = IMAGE_INSTANCE_PIXMAP_WIDTH (p);
- }
- if (height > (int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p))
- {
- y_offset += ((int) (height - IMAGE_INSTANCE_PIXMAP_HEIGHT (p))
- / 2);
- height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
- }
-
- x_output_x_pixmap (f, XIMAGE_INSTANCE (instance), tb->x + x_offset,
- tb->y + y_offset, 0, 0, 0, 0, width, height,
- 0, 0, 0, background_gc);
- }
- else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_TEXT)
- {
- /* #### We need to make the face used configurable. */
- Lisp_Object font;
- struct display_line dl;
- struct font_metric_info fm;
- Bytecount lossage;
- Lisp_Object string = IMAGE_INSTANCE_TEXT_STRING (p);
- emchar_dynarr *buf = Dynarr_new (Emchar);
-
- /* This could be true if we were called via the Expose event
- handler. Mark the button as dirty and return
- immediately. */
- if (f->window_face_cache_reset)
- {
- tb->dirty = 1;
- MARK_TOOLBAR_CHANGED;
- return;
- }
-
- font = FACE_CACHE_ELEMENT_FONT (w, DEFAULT_INDEX);
- DEVMETH (d, font_metric_info, (d, font, &fm));
- dl.ascent = fm.ascent;
- dl.descent = fm.descent;
- dl.ypos = tb->y + y_offset + fm.ascent;
-
- if (fm.ascent + fm.descent <= height)
- {
- dl.ypos += (height - fm.ascent - fm.descent) / 2;
- dl.clip = 0;
- }
- else
- {
- dl.clip = fm.ascent + fm.descent - height;
- }
-
- for (lossage = 0;
- lossage < string_length (XSTRING (string));
- lossage++)
- Dynarr_add (buf, (Emchar) string_byte (XSTRING (string), lossage));
-
- x_output_string (w, &dl, buf, tb->x + x_offset, 0, 0, width,
- DEFAULT_INDEX, 0, 0, 0, 0);
- }
-
- /* We silently ignore the image if it isn't a pixmap or text. */
- }
-
- tb->dirty = 0;
- }
-
- static int
- x_get_button_size (struct frame *f, Lisp_Object window,
- struct toolbar_button *tb, int vert, int pos)
- {
- EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
- int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
- int size;
-
- if (tb->blank)
- {
- if (!NILP (tb->down_glyph))
- size = XINT (tb->down_glyph);
- else
- size = DEFAULT_TOOLBAR_BLANK_SIZE;
- }
- else
- {
- Lisp_Object glyph = Qnil;
- struct window *w = XWINDOW (window);
-
- /* The selected glyph logic:
-
- UP: up
- DOWN: down -> up
- DISABLED: disabled -> up
- CAP-UP: cap-up -> up
- CAP-DOWN: cap-down -> cap-up -> down -> up
- CAP-DISABLED: cap-disabled -> cap-up -> disabled -> up
- */
-
- if (!NILP (w->toolbar_buttons_captioned_p))
- {
- if (tb->enabled && tb->down)
- glyph = tb->cap_down_glyph;
- else if (!tb->enabled)
- glyph = tb->cap_disabled_glyph;
-
- if (NILP (glyph))
- glyph = tb->cap_up_glyph;
- }
-
- if (NILP (glyph))
- {
- if (tb->enabled && tb->down)
- glyph = tb->down_glyph;
- else if (!tb->enabled)
- glyph = tb->disabled_glyph;
- }
-
- /* The non-captioned up button is the ultimate fallback. It is
- the only one we guarantee exists. */
- if (NILP (glyph))
- glyph = tb->up_glyph;
-
- assert (!NILP (glyph));
-
- if (vert)
- size = glyph_height (glyph, DEFAULT_INDEX, 1, window);
- else
- size = glyph_width (glyph, DEFAULT_INDEX, 1, window);
- }
-
- if (!size)
- {
- /* If the glyph doesn't have a size we'll insert a blank
- placeholder instead. */
- return XINT (f->toolbar_size[pos]);
- }
-
- size += shadow_thickness * 2;
-
- return (size);
- }
-
- #define X_OUTPUT_BUTTONS_LOOP(left) \
- do { \
- while (!NILP (button)) \
- { \
- struct toolbar_button *tb = XTOOLBAR_BUTTON (button); \
- int size, height, width; \
- \
- if (left && tb->pushright) \
- break; \
- \
- size = x_get_button_size (f, window, tb, vert, pos); \
- \
- if (vert) \
- { \
- width = bar_width; \
- if (y + size > max_pixpos) \
- height = max_pixpos - y; \
- else \
- height = size; \
- } \
- else \
- { \
- if (x + size > max_pixpos) \
- width = max_pixpos - x; \
- else \
- width = size; \
- height = bar_height; \
- } \
- \
- if (tb->x != x \
- || tb->y != y \
- || tb->width != width \
- || tb->height != height \
- || tb->dirty) \
- { \
- if (width && height) \
- { \
- tb->x = x; \
- tb->y = y; \
- tb->width = width; \
- tb->height = height; \
- \
- if (tb->blank) \
- { \
- int threed = (EQ (Qt, tb->up_glyph) ? 1 : 0); \
- x_draw_blank_toolbar_button (f, x, y, width, \
- height, threed); \
- } \
- else \
- x_output_toolbar_button (f, button); \
- } \
- } \
- \
- if (vert) \
- y += height; \
- else \
- x += width; \
- \
- if ((vert && y == max_pixpos) || (!vert && x == max_pixpos)) \
- button = Qnil; \
- else \
- button = tb->next; \
- } \
- } while (0)
-
- #define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \
- do { \
- switch (pos) \
- { \
- case TOP_TOOLBAR: \
- (frame)->top_toolbar_was_visible = flag; \
- break; \
- case BOTTOM_TOOLBAR: \
- (frame)->bottom_toolbar_was_visible = flag; \
- break; \
- case LEFT_TOOLBAR: \
- (frame)->left_toolbar_was_visible = flag; \
- break; \
- case RIGHT_TOOLBAR: \
- (frame)->right_toolbar_was_visible = flag; \
- break; \
- default: \
- abort (); \
- } \
- } while (0)
-
- static void
- x_output_toolbar (struct frame *f, enum toolbar_pos pos)
- {
- struct device *d = XDEVICE (f->device);
- int x, y, bar_width, bar_height, vert;
- int max_pixpos, right_size, right_start, blank_size;
- Lisp_Object button, window;
-
- get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 1);
- window = FRAME_SELECTED_WINDOW (f);
-
- if (vert)
- max_pixpos = y + bar_height;
- else
- max_pixpos = x + bar_width;
-
- button = FRAME_TOOLBAR_DATA (f, pos)->toolbar_buttons;
- right_size = 0;
-
- /* First loop over all of the buttons to determine how much room we
- need for left hand and right hand buttons. This loop will also
- make sure that all instances are instantiated so when we actually
- output them they will come up immediately. */
- while (!NILP (button))
- {
- struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
- int size = x_get_button_size (f, window, tb, vert, pos);
-
- if (tb->pushright)
- right_size += size;
-
- button = tb->next;
- }
-
- button = FRAME_TOOLBAR_DATA (f, pos)->toolbar_buttons;
-
- /* Loop over the left buttons, updating and outputting them. */
- X_OUTPUT_BUTTONS_LOOP (1);
-
- /* Now determine where the right buttons start. */
- right_start = max_pixpos - right_size;
- if (right_start < (vert ? y : x))
- right_start = (vert ? y : x);
-
- /* Output the blank which goes from the end of the left buttons to
- the start of the right. */
- blank_size = right_start - (vert ? y : x);
- if (blank_size)
- {
- int height, width;
-
- if (vert)
- {
- width = bar_width;
- height = blank_size;
- }
- else
- {
- width = blank_size;
- height = bar_height;
- }
-
- x_draw_blank_toolbar_button (f, x, y, width, height, 1);
-
- if (vert)
- y += height;
- else
- x += width;
- }
-
- /* Loop over the right buttons, updating and outputting them. */
- X_OUTPUT_BUTTONS_LOOP (0);
-
- if (!vert)
- {
- Lisp_Object frame;
-
- XSETFRAME (frame, f);
- DEVMETH (d, clear_region, (frame,
- DEFAULT_INDEX, FRAME_PIXWIDTH (f) - 1, y, 1,
- bar_height));
- }
-
- SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1);
-
- XFlush (DEVICE_X_DISPLAY (d));
- }
-
- static void
- x_clear_toolbar (struct frame *f, enum toolbar_pos pos, int thickness_change)
- {
- Lisp_Object frame = Qnil;
- struct device *d = XDEVICE (f->device);
- int x, y, width, height, vert;
-
- get_toolbar_coords (f, pos, &x, &y, &width, &height, &vert, 1);
- XSETFRAME (frame, f);
-
- /* The thickness_change parameter is used by the toolbar resize routines
- to clear any excess toolbar if the size shrinks. */
- if (thickness_change < 0)
- {
- if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR)
- {
- x = x + width + thickness_change;
- width = -thickness_change;
- }
- else
- {
- y = y + height + thickness_change;
- height = -thickness_change;
- }
- }
-
- SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0);
-
- DEVMETH (d, clear_region, (frame, DEFAULT_INDEX, x, y, width, height));
- XFlush (DEVICE_X_DISPLAY (d));
- }
-
- static void
- x_output_frame_toolbars (struct frame *f)
- {
- assert (FRAME_IS_X (f));
-
- if (FRAME_TOP_TOOLBAR_VISIBLE (f))
- x_output_toolbar (f, TOP_TOOLBAR);
- else if (f->top_toolbar_was_visible)
- x_clear_toolbar (f, TOP_TOOLBAR, 0);
-
- if (FRAME_BOTTOM_TOOLBAR_VISIBLE (f))
- x_output_toolbar (f, BOTTOM_TOOLBAR);
- else if (f->bottom_toolbar_was_visible)
- x_clear_toolbar (f, BOTTOM_TOOLBAR, 0);
-
- if (FRAME_LEFT_TOOLBAR_VISIBLE (f))
- x_output_toolbar (f, LEFT_TOOLBAR);
- else if (f->left_toolbar_was_visible)
- x_clear_toolbar (f, LEFT_TOOLBAR, 0);
-
- if (FRAME_RIGHT_TOOLBAR_VISIBLE (f))
- x_output_toolbar (f, RIGHT_TOOLBAR);
- else if (f->right_toolbar_was_visible)
- x_clear_toolbar (f, RIGHT_TOOLBAR, 0);
- }
-
- static void
- x_redraw_exposed_toolbar (struct frame *f, enum toolbar_pos pos, int x, int y,
- int width, int height)
- {
- int bar_x, bar_y, bar_width, bar_height, vert;
- Lisp_Object button = FRAME_TOOLBAR_DATA (f, pos)->toolbar_buttons;
-
- get_toolbar_coords (f, pos, &bar_x, &bar_y, &bar_width, &bar_height,
- &vert, 1);
-
- if (((y + height) < bar_y) || (y > (bar_y + bar_height)))
- return;
- if (((x + width) < bar_x) || (x > (bar_x + bar_width)))
- return;
-
- while (!NILP (button))
- {
- struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
-
- if (vert)
- {
- if (((tb->y + tb->height) > y) && (tb->y < (y + height)))
- tb->dirty = 1;
-
- /* If this is true we have gone past the exposed region. */
- if (tb->y > (y + height))
- break;
- }
- else
- {
- if (((tb->x + tb->width) > x) && (tb->x < (x + width)))
- tb->dirty = 1;
-
- /* If this is true we have gone past the exposed region. */
- if (tb->x > (x + width))
- break;
- }
-
- button = tb->next;
- }
-
- /* Even if none of the buttons is in the area, the blank region at
- the very least must be because the first thing we did is verify
- that some portion of the toolbar is in the exposed region. */
- x_output_toolbar (f, pos);
- }
-
- void
- x_redraw_exposed_toolbars (struct frame *f, int x, int y, int width,
- int height)
- {
- assert (FRAME_IS_X (f));
-
- if (FRAME_TOP_TOOLBAR_VISIBLE (f))
- x_redraw_exposed_toolbar (f, TOP_TOOLBAR, x, y, width, height);
-
- if (FRAME_BOTTOM_TOOLBAR_VISIBLE (f))
- x_redraw_exposed_toolbar (f, BOTTOM_TOOLBAR, x, y, width, height);
-
- if (FRAME_LEFT_TOOLBAR_VISIBLE (f))
- x_redraw_exposed_toolbar (f, LEFT_TOOLBAR, x, y, width, height);
-
- if (FRAME_RIGHT_TOOLBAR_VISIBLE (f))
- x_redraw_exposed_toolbar (f, RIGHT_TOOLBAR, x, y, width, height);
- }
-
- static void
- x_redraw_frame_toolbars (struct frame *f)
- {
- /* There are certain startup paths that lead to update_EmacsFrame in
- faces.c being called before a new frame is fully initialized. In
- particular before we have actually mapped it. That routine can
- call this one. So, we need to make sure that the frame is
- actually ready before we try and draw all over it. */
-
- if (XtIsRealized (FRAME_X_SHELL_WIDGET (f)))
- x_redraw_exposed_toolbars (f, 0, 0, FRAME_PIXWIDTH (f),
- FRAME_PIXHEIGHT (f));
- }
-
-
- static void
- x_toolbar_size_changed_in_frame (Lisp_Object specifier, struct frame *f,
- Lisp_Object oldval)
- {
- XtWidgetGeometry req, repl;
- Lisp_Object newval;
- enum toolbar_pos pos = TOP_TOOLBAR;
-
- if (!FRAME_IS_X (f))
- return;
-
- if (EQ (specifier, Vtop_toolbar_height))
- pos = TOP_TOOLBAR;
- else if (EQ (specifier, Vbottom_toolbar_height))
- pos = BOTTOM_TOOLBAR;
- else if (EQ (specifier, Vleft_toolbar_width))
- pos = LEFT_TOOLBAR;
- else if (EQ (specifier, Vright_toolbar_width))
- pos = RIGHT_TOOLBAR;
- else
- abort ();
-
- newval = f->toolbar_size[pos];
-
- /* We want the text area to stay the same size. So, we query the
- current size and then adjust it for the change in the toolbar
- size. */
-
- in_specifier_change_function++;
- if (!in_resource_setting)
- /* mirror the value in the frame resources, unless it was already
- done. */
- XtVaSetValues (FRAME_X_TEXT_WIDGET (f),
- pos == TOP_TOOLBAR ? XtNtopToolBarHeight :
- pos == BOTTOM_TOOLBAR ? XtNbottomToolBarHeight :
- pos == LEFT_TOOLBAR ? XtNleftToolBarWidth :
- XtNrightToolBarWidth,
- XINT (newval), 0);
- if (XtIsRealized (FRAME_X_CONTAINER_WIDGET (f)))
- {
- int change = XINT (newval) - XINT (oldval);
-
- req.request_mode = 0;
- /* the query-geometry method looks at the current value
- of f->toolbar_size[pos], so temporarily set it back to the
- old one. */
- f->toolbar_size[pos] = oldval;
- XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
- f->toolbar_size[pos] = newval;
-
- if (change < 0)
- x_clear_toolbar (f, pos, change);
- if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR)
- repl.width += change;
- else
- repl.height += change;
-
- MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
- EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
- repl.height);
- }
- in_specifier_change_function--;
- }
-
- static void
- x_initialize_frame_toolbar_gcs (struct frame *f)
- {
- EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
- XGCValues gcv;
- unsigned long flags = (GCForeground | GCBackground | GCGraphicsExposures);
-
- gcv.foreground = ef->emacs_frame.background_toolbar_pixel;
- gcv.background = ef->core.background_pixel;
- gcv.graphics_exposures = False;
- FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f) =
- XtGetGC ((Widget) ef, flags, &gcv);
-
- if (ef->emacs_frame.top_toolbar_shadow_pixel == -1)
- {
- ef->emacs_frame.top_toolbar_shadow_pixel =
- ef->emacs_frame.background_toolbar_pixel;
- }
- if (ef->emacs_frame.bottom_toolbar_shadow_pixel == -1)
- {
- ef->emacs_frame.bottom_toolbar_shadow_pixel =
- ef->emacs_frame.background_toolbar_pixel;
- }
-
- x_generate_shadow_pixels (f, &ef->emacs_frame.top_toolbar_shadow_pixel,
- &ef->emacs_frame.bottom_toolbar_shadow_pixel,
- ef->emacs_frame.background_toolbar_pixel,
- ef->core.background_pixel);
-
- gcv.foreground = ef->emacs_frame.top_toolbar_shadow_pixel;
- gcv.background = ef->core.background_pixel;
- gcv.graphics_exposures = False;
- flags = GCForeground | GCBackground | GCGraphicsExposures;
- if (ef->emacs_frame.top_toolbar_shadow_pixmap)
- {
- gcv.fill_style = FillOpaqueStippled;
- gcv.stipple = ef->emacs_frame.top_toolbar_shadow_pixmap;
- flags |= GCStipple | GCFillStyle;
- }
- FRAME_X_TOOLBAR_TOP_SHADOW_GC (f) = XtGetGC ((Widget) ef, flags, &gcv);
-
- gcv.foreground = ef->emacs_frame.bottom_toolbar_shadow_pixel;
- gcv.background = ef->core.background_pixel;
- gcv.graphics_exposures = False;
- flags = GCForeground | GCBackground | GCGraphicsExposures;
- if (ef->emacs_frame.bottom_toolbar_shadow_pixmap)
- {
- gcv.fill_style = FillOpaqueStippled;
- gcv.stipple = ef->emacs_frame.bottom_toolbar_shadow_pixmap;
- flags |= GCStipple | GCFillStyle;
- }
- FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f) = XtGetGC ((Widget) ef, flags, &gcv);
-
- #ifdef HAVE_XPM
- FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f) =
- FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
- #else
- {
- struct device *d = XDEVICE (f->device);
- Display *dpy = DEVICE_X_DISPLAY (d);
-
- gcv.background = WhitePixelOfScreen (DefaultScreenOfDisplay (dpy));
- gcv.foreground = BlackPixelOfScreen (DefaultScreenOfDisplay (dpy));
- gcv.graphics_exposures = False;
- flags = GCForeground | GCBackground | GCGraphicsExposures;
- FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f) =
- XtGetGC ((Widget) ef, flags, &gcv);
- }
- #endif
- }
-
- static void
- x_release_frame_toolbar_gcs (struct frame *f)
- {
- Widget ew = (Widget) FRAME_X_TEXT_WIDGET (f);
- XtReleaseGC (ew, FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f));
- /* If compiled with XPM support, this is a pointer to the same GC as
- FRAME_X_BLANK_BACKGROUND_GC so we need to make sure we don't
- release it twice. */
- #ifndef HAVE_XPM
- XtReleaseGC (ew, FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f));
- #endif
- XtReleaseGC (ew, FRAME_X_TOOLBAR_TOP_SHADOW_GC (f));
- XtReleaseGC (ew, FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f));
-
- /* Seg fault if we try and use these again. */
- FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f) = (GC) -1;
- FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f) = (GC) -1;
- FRAME_X_TOOLBAR_TOP_SHADOW_GC (f) = (GC) -1;
- FRAME_X_TOOLBAR_BOTTOM_SHADOW_GC (f) = (GC) -1;
- }
-
- static void
- x_initialize_frame_toolbars (struct frame *f)
- {
- EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
-
- if (ef->emacs_frame.toolbar_shadow_thickness < MINIMUM_SHADOW_THICKNESS)
- {
- XtVaSetValues (FRAME_X_TEXT_WIDGET (f), XtNtoolBarShadowThickness,
- MINIMUM_SHADOW_THICKNESS, 0);
- }
-
- x_initialize_frame_toolbar_gcs (f);
- }
-
- /* This only calls one function but we go ahead and create this in
- case we ever do decide that we need to do more work. */
- static void
- x_free_frame_toolbars (struct frame *f)
- {
- x_release_frame_toolbar_gcs (f);
- }
-
-
- /************************************************************************/
- /* initialization */
- /************************************************************************/
-
- void
- device_type_create_toolbar_x (void)
- {
- DEVICE_HAS_METHOD (x, output_frame_toolbars);
- DEVICE_HAS_METHOD (x, initialize_frame_toolbars);
- DEVICE_HAS_METHOD (x, free_frame_toolbars);
- DEVICE_HAS_METHOD (x, output_toolbar_button);
- DEVICE_HAS_METHOD (x, redraw_frame_toolbars);
- DEVICE_HAS_METHOD (x, toolbar_size_changed_in_frame);
- }
-